//
// Created by pzw on 24-3-19.
//

#ifndef QTTEST_ITROVERVIEW_H
#define QTTEST_ITROVERVIEW_H

#include <iterator>
#include <algorithm>
#include <map>
#include <set>
#include <vector>
#include <list>
#include <iostream>
#include <string>

/**
 * <p>
 * 迭代器模型
 * 1. 迭代器是容器与算法的中介者，是它们通信的桥梁；
 * 2. 迭代器被设计成指针，++，--，+=，<，!=等操作符全部重载，完全符合指针操作习惯；
 * </p>
 *
 * <p>
 * 迭代器类别
 * 1. 输入迭代器(input itr)：istream提供了这种迭代器；
 * 2. 输出迭代器(output itr)：ostream提供了这种迭代器；
 * 3. 前向迭代器(forward itr)：向前遍历序列；forward_list提供了这种迭代器；
 * 4. 双向迭代器(bidirectional itr)：list，map，set提供了这种迭代器；
 * 5. 随机访问迭代器(random-access itr)：vector提供了这种迭代器；
 * </p>
 *
 * <p>
 * 迭代器萃取
 * 1. typename std::vector<Tp>::iterator::value_type 迭代器值类型萃取；
 * 2. typename std::vector<Tp>::iterator::pointer    迭代器值类型指针萃取；
 * 3. typename std::vector<Tp>::iterator::reference  迭代器值类型引用萃取；
 * </p>
 *
 * <p>
 * 迭代器操作
 * 1. 完全符合指针操作习惯，这是因为迭代器重载了所有指针的操作符，使得迭代器可以按照指针习惯进行操作；
 * 2. ++p，p++，*p，--p，p--，p[n]，p->m，p==q，p!=q，p<q，p<=q，p>q，p+=n，p-=n，q=p+n，q=p-n；
 * 3. advance(p, n)，x=distance(p, q)，q=next(p,n)，q=next(p)，q=prev(p,n)，q=prev(p)；
 * </p>
 *
 * @author pzw
 * @date 24-3-19
 */
template<typename Tp>
class ItrOverview {
private:
    /**
     * 这，就是类型萃取
     */
    using value_type = typename std::vector<Tp>::iterator::value_type;
    using pointer = typename std::vector<Tp>::iterator::pointer;
    using reference = typename std::vector<Tp>::iterator::reference;
private:
    value_type x = 3;
    pointer y = &x;
    reference z = x;

public:
    explicit ItrOverview(value_type value) : x(value) {
    }

    ~ItrOverview() = default;

public:
    template<typename Container>
    static void forEachContainer(const Container &cnt) {
        /* 这里就是类型萃取的应用，我不关心你什么元素，我直接类型萃取，进行遍历 */
        for (typename Container::value_type elem: cnt) {
            std::cout << elem << ", ";
        }
        std::cout << std::endl;
    }

    template<typename Container>
    static void forEachContainer2(const Container &cnt) {
        /* 这里就是类型萃取的应用，我不关心你什么元素，我直接类型萃取，进行遍历 */
        for (typename Container::value_type elem: cnt) {
            /* 要使用这个，你必须对你的类重载操作符<< */
            elem << (std::cout << ", ");
        }
        std::cout << std::endl;
    }

public:
    std::string toString() const {
        std::string text{};
        text.append(std::to_string(x));
        text.append(std::to_string(*y));
        text.append(std::to_string(z));
        return text;
    }
};

int ItrOverview_main();

#endif //QTTEST_ITROVERVIEW_H
